﻿using System;
using System.Data.SqlClient;
using System.Collections.Generic;
using System.IO;
using System.Xml;

namespace DataCoreTechnologies.SqlServer
{
   /// <summary>
   /// Contains information about a server that has an instance of SqlServer running on it and contains
   /// 1 or more databases.
   /// </summary>
   public sealed partial class Server
   {
      #region Public
      //Constructors
      /// <summary>
      /// Creates a server located with the location and authentication information specified by
      /// the connection string in the parameter.
      /// </summary>
      /// <param name="sb">The location and authentication information for this server.</param>
      public Server(SqlConnectionStringBuilder sb)
      {
        InstanceId = System.Guid.NewGuid();
        Name = sb.DataSource;

        _sqlConnectionStringBuilder = sb;
      }
      //Public Properties
      /// <summary>
      /// The date this server's information was loaded into memory.
      /// </summary>
      public DateTime LoadedOn { get; private set; }
      /// <summary>
      /// A number that uniquely identifies this class instance.
      /// </summary>
      public Guid InstanceId { get; private set; }
      //Authentication properties
      /// <summary>
      /// Returns the location and authentication information for this server.
      /// </summary>
      public SqlConnectionStringBuilder ConnectionStringBuilder
      {
        get
        {
           return _sqlConnectionStringBuilder;
        }
      }
      /// <summary>
      /// The title used to identify this server on the network.
      /// </summary>
      public string Name { get; internal set; }
      /// <summary>
      /// The version of SqlServer running on this server.
      /// </summary>
      public string Version { get; internal set; }
      /// <summary>
      /// The product name for this server.
      /// </summary>
      public string Product { get; private set; }
      /// <summary>
      /// The version of windows running on this server.
      /// </summary>
      public string OperatingSystem { get; private set; }
      /// <summary>
      /// The platform running on this server.
      /// </summary>
      public string Platform { get; private set; }
      /// <summary>
      /// The default language used by this server.
      /// </summary>
      public string Language { get; private set; }
      /// <summary>
      /// The amount of memory installed on this server.
      /// </summary>
      public int Memory { get; private set; }
      /// <summary>
      /// The amount of processors on this server.
      /// </summary>
      public int NumProcessors { get; private set; }
      /// <summary>
      /// The root directory for this data files on this SqlServer instance.
      /// </summary>
      public string RootDirectory { get; private set; }
      /// <summary>
      /// The default collation being used by this server.
      /// </summary>
      public string CollationName { get; private set; }
      /// <summary>
      /// Indicator stating whether this server is part of a cluster.
      /// </summary>
      public Boolean IsClustered { get; private set; }
      /// <summary>
      /// Indicator stating whether this server allows sql authentication
      /// </summary>
      public Boolean AllowSqlAuthentication { get; private set; }
      /// <summary>
      /// The audit level being used by this server.
      /// </summary>
      public string AuditLevel { get; private set; }
      /// <summary>
      /// Indicator stating whether this server has C2 auditing enabled.
      /// </summary>
      public Boolean EnableC2Auditing { get; private set; }
      /// <summary>
      /// Indicator stating whether this server allows triggers to fire other triggers.
      /// </summary>
      public Boolean AllowTriggersToFireTriggers { get; private set; }
      /// <summary>
      /// The default language being used on this server.
      /// </summary>
      public string DefaultLanguage { get; private set; }
      /// <summary>
      /// Indicator stating whether stored procedures are being scanned at start up.
      /// </summary>
      public Boolean ScanStoredProcsAtStartup { get; private set; }
      /// <summary>
      /// The two digit cutoff being used by this server.
      /// </summary>
      public int TwoDigitCutoff { get; private set; }
      /// <summary>
      /// The size of network packets being used by this server.
      /// </summary>
      public int NetworkPacketSize { get; private set; }
      /// <summary>
      /// The length of time this server will allow connection attempts to run before timing them out.
      /// </summary>
      public int RemoteLoginTimeout { get; private set; }
      /// <summary>
      /// The length of time this server will allow queries to run before timing them out.
      /// </summary>
      public int RemoteQueryTimeout { get; private set; }
      /// <summary>
      /// The maximum number of locks this server will allow.
      /// </summary>
      public int MaxNumberOfLocks { get; private set; }
      /// <summary>
      /// The length of time this server will attempt to wait for a query.
      /// </summary>
      public int QueryWait { get; private set; }
      /// <summary>
      /// A collection of databases located on this server
      /// </summary>
      public IEnumerable<Database> Databases
      {
         get
         {
            for (int index = 0; index < _databases.Count; index++)
            {
               yield return _databases[index];
            }
         }
      }
      //Public Methods
      /// <summary>
      /// Removes any existing databases and loads a list of databases contained in the server.
      /// Throws InvalidOperationException when attempting to load information 
      /// from SqlServer 6.5 or 7.0
      /// </summary>
      public void LoadDatabaseList()
      {
         Diagnostic.WriteLine("Started loading database list");
         RemoveDatabases(null);
         if (Convert.ToInt32(Version.Substring(0, 1)) >= 6
             && Convert.ToInt32(Version.Substring(0, 1)) <= 7)
             throw new InvalidOperationException(@"Error: Version 6.5 and 7.0 of Sql Server are not currently supported");
         else if (Version.Substring(0, 1) == "8")
         {
             //http://msdn.microsoft.com/en-us/library/aa258262(SQL.80).aspx
             string sql = @"
                 SELECT name, dbid,
                     CAST(dtb.status & 1 AS bit) AS [AutoClose],
                     CAST(dtb.status & 4194304 AS bit) AS [AutoShrink],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAnsiNullDefault') AS bit) AS [AnsiNullDefault],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAnsiNullsEnabled') AS bit) AS [AnsiNullsEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAnsiPaddingEnabled') AS bit) AS [AnsiPaddingEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAnsiWarningsEnabled') AS bit) AS [AnsiWarningsEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsArithmeticAbortEnabled') AS bit) AS [ArithmeticAbortEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAutoCreateStatistics') AS bit) AS [AutoCreateStatistics],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsAutoUpdateStatistics') AS bit) AS [AutoUpdateStatistics],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsCloseCursorsOnCommitEnabled') AS bit) AS [CloseCursorsOnCommitEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsNullConcat') AS bit) AS [ConcatenateNullYieldsNull],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsNumericRoundAbortEnabled') AS bit) AS [NumericRoundAbortEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsQuotedIdentifiersEnabled') AS bit) AS [QuotedIdentifiersEnabled],
                     CAST(DATABASEPROPERTY(dtb.name, 'IsReadOnly') AS bit) AS [ReadOnly],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsRecursiveTriggersEnabled') AS bit) AS [RecursiveTriggersEnabled],
                     CAST(DATABASEPROPERTYEX(dtb.name, 'IsLocalCursorsDefault') AS bit) AS [LocalCursorsDefault],
                     CASE WHEN 1=DATABASEPROPERTYEX(dtb.name, 'IsTornPageDetectionEnabled') THEN 1 ELSE 0 END AS [PageVerify],
                     CASE DATABASEPROPERTYEX(dtb.name, 'Recovery') WHEN 'SIMPLE' THEN 3 WHEN 'BULK_LOGGED' THEN 2 ELSE /*FULL*/ 1 END AS [RecoveryModel],
                    DATABASEPROPERTYEX(dtb.name, 'Recovery') AS [RecoveryModelDescription],
                     CASE CONVERT(sysname,DATABASEPROPERTYEX(dtb.name, 'UserAccess')) WHEN 'SINGLE_USER' THEN 1 WHEN 'RESTRICTED_USER' THEN 2 ELSE /*MULTI_USER*/ 0 END AS [UserAccess],
                    CONVERT(sysname,DATABASEPROPERTYEX(dtb.name, 'UserAccess')) AS [UserAccessDescription],
                     crdate, cmptlevel, version,
                     convert(sysname, serverproperty(N'collation')) AS [Collation]
                 FROM master.dbo.sysdatabases AS dtb
                 WHERE dtb.name not in ('master', 'model', 'tempdb', 'msdb')
                           ";
             SqlDataReader reader = GetDataReader(sql);
             while (reader.Read())
             {
                var database = Factory.GetDatabase(this);

                database.Name = (string)reader["name"];
                database.Id = Convert.ToInt32(reader["dbid"]);

                database.CreateDate = (DateTime)reader["crdate"];
                database.CompatibilityLevel = Convert.ToInt32(reader["cmptlevel"]);
                //database.Version
                database.IsAutoCloseOn = Convert.ToBoolean(reader["AutoClose"]);
                database.IsAutoShrinkOn = Convert.ToBoolean(reader["AutoShrink"]);
                database.IsAnsiNullDefaultOn = Convert.ToBoolean(reader["AnsiNullDefault"]);
                database.IsAnsiNullsOn = Convert.ToBoolean(reader["AnsiNullsEnabled"]);
                database.IsAnsiPaddingOn = Convert.ToBoolean(reader["AnsiPaddingEnabled"]);
                database.IsAnsiWarningsOn = Convert.ToBoolean(reader["AnsiWarningsEnabled"]);
                database.IsArithAbortOn = Convert.ToBoolean(reader["ArithmeticAbortEnabled"]);
                database.IsAutoCreateStatsOn = Convert.ToBoolean(reader["AutoCreateStatistics"]);
                database.IsAutoUpdateStatsOn = Convert.ToBoolean(reader["AutoUpdateStatistics"]);
                database.IsCursorCloseOnCommitOn = Convert.ToBoolean(reader["CloseCursorsOnCommitEnabled"]);
                database.IsConcatNullYieldsNullOn = Convert.ToBoolean(reader["ConcatenateNullYieldsNull"]);
                database.IsNumericRoundAbortOn = Convert.ToBoolean(reader["NumericRoundAbortEnabled"]);
                database.IsQuotedIdentifierOn = Convert.ToBoolean(reader["QuotedIdentifiersEnabled"]);
                database.IsReadOnly = Convert.ToBoolean(reader["ReadOnly"]);
                database.IsRecursiveTriggersOn = Convert.ToBoolean(reader["RecursiveTriggersEnabled"]);
                database.IsLocalCursorDefault = Convert.ToBoolean(reader["LocalCursorsDefault"]);
                database.PageVerifyOption = Convert.ToInt32(reader["PageVerify"]);
                if (database.PageVerifyOption == 1)
                    database.PageVerifyOptionDescription = "True";
                else
                    database.PageVerifyOptionDescription = "False";
                database.RecoveryModel = Convert.ToInt32(reader["RecoveryModel"]);
                database.RecoveryModelDescription = (string)reader["RecoveryModelDescription"];
                database.UserAccess = Convert.ToInt32(reader["UserAccess"]);
                database.UserAccessDescription = (string)reader["UserAccessDescription"];
                database.CollationName = (string)reader["Collation"];
                
                AddDatabase(database);
             }
             reader.Close();
         }
         else
         {
             //http://support.microsoft.com/kb/310107
             string sql = @"select * from sys.databases where name not in ('master', 'model', 'msdb', 'tempdb') order by name";
             SqlDataReader reader = GetDataReader(sql);
             while (reader.Read())
             {
                 var database = Factory.GetDatabase(this);

                 database.Name = (string)reader["name"];
                 database.Id = (int)reader["database_id"];
                 if (reader.IsDBNull(2) == true)
                     database.SourceDatabaseId = null;
                 else
                     database.SourceDatabaseId = (int)reader["source_database_id"];
                 //database.Property.Owner = (byte)reader["owner_sid"];
                 database.CreateDate = (DateTime)reader["create_date"];
                 database.CompatibilityLevel = (byte)reader["compatibility_level"];
                 if (reader.IsDBNull(6) == true)
                     database.CollationName = null;
                 else
                     database.CollationName = (string)reader["collation_name"];
                 //Database.SetDatabaseProperty(Data.DatabaseProperty.UserAccess, (byte)reader["user_access"]);
                 database.UserAccessDescription = (string)reader["user_access_desc"];
                 database.IsReadOnly = (bool)reader["is_read_only"];
                 database.IsAutoCloseOn = (bool)reader["is_auto_close_on"];
                 database.IsAutoShrinkOn = (bool)reader["is_auto_shrink_on"];
                 //Database.SetDatabaseProperty(Data.DatabaseProperty.State, (byte)reader["state"]);
                 database.StateDescription = (string)reader["state_desc"];
                 database.IsInStandby = (bool)reader["is_in_standby"];
                 database.IsCleanlyShutdown = (bool)reader["is_cleanly_shutdown"];
                 database.IsSupplementalLoggingEnabled = (bool)reader["is_supplemental_logging_enabled"];
                 //database.Property.SnapshotIsolationState, (byte)reader["snapshot_isolation_state"]);
                 database.SnapshotIsolationStateDescription = (string)reader["snapshot_isolation_state_desc"];
                 database.IsReadCommittedSnapshotOn = (bool)reader["is_read_committed_snapshot_on"];
                 //Database.SetDatabaseProperty(Data.DatabaseProperty.RecoveryModel, (byte)reader["recovery_model"]);
                 database.RecoveryModelDescription = (string)reader["recovery_model_desc"];
                 //Database.SetDatabaseProperty(Data.DatabaseProperty.PageVerifyOption, (byte)reader["page_verify_option"]);
                 database.PageVerifyOptionDescription = (string)reader["page_verify_option_desc"];

                 database.IsAutoCreateStatsOn = (bool)reader["is_auto_create_stats_on"];
                 database.IsAutoUpdateStatsOn = (bool)reader["is_auto_update_stats_on"];
                 database.IsAutoUpdateStatsAsyncOn = (bool)reader["is_auto_update_stats_async_on"];
                 database.IsAnsiNullDefaultOn = (bool)reader["is_ansi_null_default_on"];
                 database.IsAnsiNullsOn = (bool)reader["is_ansi_nulls_on"];
                 database.IsAnsiPaddingOn = (bool)reader["is_ansi_padding_on"];
                 database.IsAnsiWarningsOn = (bool)reader["is_ansi_warnings_on"];
                 database.IsArithAbortOn = (bool)reader["is_arithabort_on"];
                 database.IsConcatNullYieldsNullOn = (bool)reader["is_concat_null_yields_null_on"];
                 database.IsNumericRoundAbortOn = (bool)reader["is_numeric_roundabort_on"];
                 database.IsQuotedIdentifierOn = (bool)reader["is_quoted_identifier_on"];
                 database.IsRecursiveTriggersOn = (bool)reader["is_recursive_triggers_on"];
                 database.IsCursorCloseOnCommitOn = (bool)reader["is_cursor_close_on_commit_on"];
                 database.IsLocalCursorDefault = (bool)reader["is_local_cursor_default"];
                 database.IsFullTextEnabled = (bool)reader["is_fulltext_enabled"];
                 database.IsTrustWorthyOn = (bool)reader["is_trustworthy_on"];
                 database.IsDBChainingOn = (bool)reader["is_db_chaining_on"];
                 database.IsParameterizationForced = (bool)reader["is_parameterization_forced"];
                 database.IsMasterKeyEncryptedByServer = (bool)reader["is_master_key_encrypted_by_server"];
                 database.IsPublished = (bool)reader["is_published"];
                 database.IsSubscribed = (bool)reader["is_subscribed"];
                 database.IsMergePublished = (bool)reader["is_merge_published"];
                 database.IsDistributor = (bool)reader["is_distributor"];
                 database.IsSyncWithBackup = (bool)reader["is_sync_with_backup"];

                 database.ServiceBrokerGuid = (Guid)reader["service_broker_guid"];
                 database.IsBrokerEnabled = (bool)reader["is_broker_enabled"];
                 //database.Property.LogReuseWait = (byte)reader["log_reuse_wait"];
                 database.LogReuseWaitDescription = (string)reader["log_reuse_wait_desc"];
                 database.IsDateCorrelationOn = (bool)reader["is_date_correlation_on"];

                 AddDatabase(database);
             }
             reader.Close();
         }
         Diagnostic.WriteLine("Finished loading database list");
      }
      /// <summary>
      /// Opens a connection to the server and loads all relevant information.
      /// </summary>
      public void Connect()
      {
         OpenConnection();
         LoadServerInformation();
      }
      /// <summary>
      /// Closes a connection to the server if open. Doesn't remove any existing information.
      /// </summary>
      public void Disconnect()
      {
         if (_SqlConnection.State == System.Data.ConnectionState.Open) _SqlConnection.Close();
      }
      /// <summary>
      /// Closes and reopens the connection to the server.
      /// </summary>
      public void ResetConnection()
      {
         if (_SqlConnection.State == System.Data.ConnectionState.Open) _SqlConnection.Close();
         OpenConnection();
      }
      /// <summary>
      /// Removes references to existing database or databases from the server.
      /// </summary>
      /// <param name="database">Null is all databases otherwise pass in the database to be removed</param>
      public void RemoveDatabases(Database database) 
      {
        if (database == null)
           _databases.Clear();
        else
        {
           foreach (Database db in _databases)
           {
              if (db == database) _databases.Remove(db);
           }
        }
      }
      #endregion Public
      #region Internal
      //Internal Properties
      /// <summary>
      /// Sets the name of the database that should be used by connections to this server.
      /// </summary>
      internal string DefaultDatabase
      {
         set
         {
            _sqlConnectionStringBuilder.InitialCatalog = value;
         }
      }
      //Internal Methods
      /// <summary>
      /// Associates a database with this server.
      /// </summary>
      /// <param name="database">The database that belongs to this server.</param>
      internal void AddDatabase(Database database) { _databases.Add(database); }
      /// <summary>
      /// Changes the active database to the 
      /// </summary>
      /// <param name="databaseName"></param>
      internal void ChangeActiveDatabase(string databaseName)
      {
         //http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.changedatabase.aspx
         _SqlConnection.ChangeDatabase(databaseName);
      }
      /// <summary>
      /// Returns the data reader returned by running a sql statement against the database.
      /// </summary>
      /// <param name="sql">The sql statement that returns the expected results.</param>
      /// <returns>The data reader returned by the database.</returns>
      internal SqlDataReader GetDataReader(string sql)
      {
         SqlCommand cmd = new SqlCommand(sql, _SqlConnection);
         return cmd.ExecuteReader();
      }
      /// <summary>
      /// Returns a single value returned by running a sq statement against the database.
      /// </summary>
      /// <param name="sql">The sql statement that returns the expected value.</param>
      /// <returns>The single value returned by the database.</returns>
      internal Object GetScaler(string sql)
      {
         SqlCommand cmd = new SqlCommand(sql, _SqlConnection);
         return cmd.ExecuteScalar();
      }
      #endregion Internal
      #region Private
      //Private variables
      private SqlConnection _SqlConnection = new SqlConnection();
      private List<Database> _databases = new List<Database>();
      private SqlConnectionStringBuilder _sqlConnectionStringBuilder = null;
      //Private methods
      private void OpenConnection()
      {
         //http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.aspx
         //http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.open.aspx
         if (_SqlConnection.State == System.Data.ConnectionState.Open) _SqlConnection.Close();
         _SqlConnection.ConnectionString = _sqlConnectionStringBuilder.ConnectionString;
         _SqlConnection.Open();
         string sql = @"SELECT SERVERPROPERTY('productversion')";
         Version = (string)GetScaler(sql);
      }
      private void LoadServerInformation()
      {
         LoadedOn = DateTime.Now;

         if (Version.Substring(0, 1) == "8" || Version.Substring(0, 1) == "9" 
             || Version.Substring(0, 2) == "10")
         {
             #region Server Properties
             Diagnostic.WriteLine("Started loaded Server Properies");
             string sql = @"
                         create table #SVer(ID int,  Name  sysname, Internal_Value int, Value nvarchar(512))
                         insert #SVer exec master.dbo.xp_msver
                         			
                         declare @SmoRoot nvarchar(512)
                         exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\Setup', N'SQLPath', @SmoRoot OUTPUT
                         			
                         SELECT
                         (select Value from #SVer where Name = N'ProductName') AS [Product],
                         SERVERPROPERTY(N'ProductVersion') AS [VersionString],
                         (select Value from #SVer where Name = N'Language') AS [Language],
                         (select Value from #SVer where Name = N'Platform') AS [Platform],
                         CAST(SERVERPROPERTY(N'Edition') AS sysname) AS [Edition],
                         (select Internal_Value from #SVer where Name = N'ProcessorCount') AS [Processors],
                         (select Value from #SVer where Name = N'WindowsVersion') AS [OSVersion],
                         (select Internal_Value from #SVer where Name = N'PhysicalMemory') AS [PhysicalMemory],
                         CAST(SERVERPROPERTY('IsClustered') AS bit) AS [IsClustered],
                         @SmoRoot AS [RootDirectory],
                         convert(sysname, serverproperty(N'collation')) AS [Collation]

                         drop table #SVer
                       ";
             var reader = GetDataReader(sql);
             while (reader.Read())
             {
                 Product = (string)reader["Product"];
                 Language = (string)reader["Language"];
                 Platform = (string)reader["Platform"];
                 OperatingSystem = (string)reader["OSVersion"];
                 Memory = Convert.ToInt32(reader["PhysicalMemory"]);
                 IsClustered = Convert.ToBoolean(reader["IsClustered"]);
                 CollationName = (string)reader["Collation"];
                 RootDirectory = (string)reader["RootDirectory"];
                 NumProcessors = Convert.ToInt32(reader["Processors"]);
             }
             reader.Close();
             Diagnostic.WriteLine("Finished loading server properties");
             #endregion
             #region Security Settings
             Diagnostic.WriteLine("Started loading server settings");
             sql = @"
                     declare @SmoLoginMode int
                     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'LoginMode', @SmoLoginMode OUTPUT

                     declare @SmoAuditLevel int
                     exec master.dbo.xp_instance_regread N'HKEY_LOCAL_MACHINE', N'Software\Microsoft\MSSQLServer\MSSQLServer', N'AuditLevel', @SmoAuditLevel OUTPUT
                     			
                     SELECT
                     (case when @SmoLoginMode < 3 then @SmoLoginMode else 9 end) AS [LoginMode],
                     @SmoAuditLevel AS [AuditLevel]
                    ";
             reader = GetDataReader(sql);
             while (reader.Read())
             {
                 if (Convert.ToInt32(reader["LoginMode"]) == 2)
                     AllowSqlAuthentication = true;
                 else
                     AllowSqlAuthentication = false;

                 switch (Convert.ToInt32(reader["AuditLevel"]))
                 {
                     case 0:
                         AuditLevel = "None";
                         break;
                     case 1:
                         AuditLevel = "Failed logins only";
                         break;
                     case 2:
                         AuditLevel = "Successful logins only";
                         break;
                     case 3:
                         AuditLevel = "Both failed and successful logins";
                         break;
                 }
             }
             reader.Close();
             Diagnostic.WriteLine("Finished loading server settings");
             #endregion
             #region Server Options
             Diagnostic.WriteLine("Started loading server options");
             //http://msdn.microsoft.com/en-us/library/aa260396(SQL.80).aspx
             sql = @"
                 select config, value
                 from master.dbo.syscurconfigs
                 WHERE config IN (115, 544, 124, 1547, 1519, 1520, 1127, 505, 20, 106, 1541)
                    ";
             reader = GetDataReader(sql);
             while (reader.Read())
             {
                 switch (Convert.ToInt32(reader["config"]))
                 {
                     case 106:
                         MaxNumberOfLocks = Convert.ToInt32(reader["value"]);
                         break;
                     case 115:
                         AllowTriggersToFireTriggers = Convert.ToBoolean(reader["value"]);
                         break;
                     case 1127:
                         TwoDigitCutoff = Convert.ToInt32(reader["value"]);
                         break;
                     case 124:
                         DefaultLanguage = Language;
                         break;
                     case 505:
                         NetworkPacketSize = Convert.ToInt32(reader["value"]);
                         break;
                     case 1519:
                         RemoteLoginTimeout = Convert.ToInt32(reader["value"]);
                         break;
                     case 1520:
                         RemoteQueryTimeout = Convert.ToInt32(reader["value"]);
                         break;
                     case 1541:
                         QueryWait = Convert.ToInt32(reader["value"]);
                         break;
                     case 1547:
                         ScanStoredProcsAtStartup = Convert.ToBoolean(reader["value"]);
                         break;
                     case 544:
                         EnableC2Auditing = Convert.ToBoolean(reader["value"]);
                         break;
                 }
             }
             reader.Close();
             Diagnostic.WriteLine("Finished loading server options");
             Diagnostic.WriteLine("");
             #endregion
         }
      }
      #endregion Private
   }
}
